﻿using gt.rediscache.core.Entry;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace gt.rediscache
{
    /// <summary>
    /// 缓存配置
    /// </summary>
    [XmlRoot("RedisCacheConfig")]
    public class RedisCacheConfig : RedisConfigBase
    {
        /// <summary>
        /// 应用名称
        /// </summary>
        public string ApplicationName { get; set; }
        /// <summary>
        /// 应用缓存信息
        /// </summary>
        [XmlArray("ApplicationCaches"), XmlArrayItem("ApplicationCache")]
        public List<ApplicationCacheConfig> ApplicationCaches { get; set; }
        /// <summary>
        /// 缓存配置路径
        /// </summary>
        [XmlArray("CachePathMappings"), XmlArrayItem("CachePath")]
        public List<CachePathConfig> CachePathMappings { get; set; }
        /// <summary>
        /// 上报客户端驱动状态信息URL
        /// </summary>
        public string RedisCacheUrl { get; set; }
        public string NotifyUrl { get; set; }
        /// <summary>
        /// OuYang = A,ZhouPu = B,Wanguo=E
        /// </summary>
        public string IDC { get; set; }

        public override void ConfigChanged()
        {
            //Task.Run(() =>
            //{
            //    try
            //    {
            //        RedisCacheConfig realConfig = RedisConfigManager.GetRedisCacheConfigFromCache();
            //        if (realConfig != null && realConfig.ApplicationCaches != null)
            //        {
            //            foreach (var m in realConfig.ApplicationCaches)
            //            {
            //                IRedisClient client = RedisCacheManager.GetClient(m.Name);
            //                var servers = client.GetClientServers();
            //                foreach (var clientServer in servers)
            //                {
            //                    if (m.SwitchNodes != null
            //                        && m.SwitchNodes.Exists(e => string.Equals(clientServer.Node.Name, e,
            //                            System.StringComparison.CurrentCultureIgnoreCase)))
            //                    {
            //                        clientServer.ResetAvailableStatus(1);
            //                    }
            //                    else
            //                    {
            //                        clientServer.ResetAvailableStatus(2);
            //                    }
            //                }
            //            }
            //        }
            //    }
            //    catch
            //    { }
            //});
        }
    }

    public class CachePathConfig
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        [XmlAttribute("path")]
        public string Path { get; set; }
    }

    /// <summary>
    /// 应用缓存
    /// </summary>
    public class ApplicationCacheConfig
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        [XmlAttribute("main_cache")]
        public string MainCache { get; set; }
        [XmlAttribute("backup_cache")]
        public string BackupCache { get; set; }
        //[XmlAttribute("monthlive_cache")]
        //public string MonthLiveCache { get; set; }
        public List<string> SwitchNodes { get; set; }

        private BackupModeEnum backupMode = BackupModeEnum.None;
        /// <summary>
        /// 备用缓存切换功能开启
        /// </summary>
        public BackupModeEnum BackupMode { get { return backupMode; } set { backupMode = value; } }

        /// <summary>
        /// 延迟恢复时间
        /// useful in MultipleAndBackup mode
        /// </summary>
        public int DelayedRecoverySeconds { get { return delayedRecoverySeconds; } set { delayedRecoverySeconds = value; } }
        private int delayedRecoverySeconds = -1;

        /// <summary>
        /// 主从切换等待时间
        /// useful in MultipleAndBackup mode
        /// </summary>
        public int RedisFailoverWaitSeconds { get { return redisFailoverWaitSeconds; } set { redisFailoverWaitSeconds = value; } }
        private int redisFailoverWaitSeconds = 10;

        public virtual string GetAppCacheName()
        {
            return this.Name;
        }
        public CachePoolConfig MainCachePool
        {
            get
            {
                if (string.IsNullOrEmpty(this.MainCache)) return null;
                return RedisConfigManager.GetCachePoolFromCache<CachePoolConfig>(this.MainCache);
            }
        }
        public CachePoolConfig BackupCachePool
        {
            get
            {
                if (string.IsNullOrEmpty(this.BackupCache)) return null;
                return RedisConfigManager.GetCachePoolFromCache<CachePoolConfig>(this.BackupCache);
            }
        }
        //public CachePoolConfig MonthLiveCachePool
        //{
        //    get
        //    {
        //        if (string.IsNullOrEmpty(this.MonthLiveCache)) return null;
        //        return RedisConfigManager.GetCachePoolFromCache<CachePoolConfig>(this.MonthLiveCache);
        //    }
        //}
    }

    /// <summary>
    /// 缓存池信息
    /// </summary>
    [XmlRoot("CachePool")]
    public class CachePoolConfig : RedisConfigBase
    {
        public string Name { get; set; }
        public PoolMode Mode { get; set; }
        [XmlArray("Nodes"), XmlArrayItem("RedisNode")]
        public List<RedisNodeConfig> Nodes { get; set; }

        public override void ConfigChanged()
        {
            base.ConfigChanged();
        }
    }

    public class RedisNodeConfig
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        public string Master { get; set; }
        public List<string> Slaves { get; set; }
        /// </summary>
        public int SlotFrom { get; set; }
        /// <summary>
        /// slot End
        /// useful in Multipler or MultipleAndBackup type
        /// </summary>
        public int SlotTo { get; set; }

        /// <summary>
        /// Redis DB 库
        /// 默认-1
        /// </summary>
        private int db = -1;
        [XmlAttribute("db")]
        public int DB
        {
            get { return db; }
            set { db = value; }
        }

        /// <summary>
        /// 缓存Auth设置
        /// </summary>
        public string Auth { get; set; }

        public override string ToString()
        {
            StringBuilder s = new StringBuilder(Name);
            s.Append("(");
            string slaveIps = Slaves == null || Slaves.Count == 0 ? ""
                : string.Join(",", Slaves);
            s.Append(Master);
            if (!string.IsNullOrEmpty(slaveIps)) s.Append(",").Append(slaveIps);
            s.Append(")");
            return s.ToString();
        }
    }
}
